package com.kyg.tjtoolmanager.controller;

import com.alibaba.fastjson.JSONArray;
import com.kyg.tjtoolmanager.App;
import com.kyg.tjtoolmanager.db.SQLiteUtils;
import com.kyg.tjtoolmanager.module.Reader;
import com.kyg.tjtoolmanager.module.Shelves;
import com.kyg.tjtoolmanager.module.WareHouse;
import com.kyg.tjtoolmanager.net.http.HttpBack;
import com.kyg.tjtoolmanager.net.http.HttpEntity;
import com.kyg.tjtoolmanager.net.http.HttpService;
import com.kyg.tjtoolmanager.net.http.HttpURL;
import com.kyg.tjtoolmanager.ui.ProgressStage;
import com.kyg.tjtoolmanager.ui.StageUIHelper;
import com.kyg.tjtoolmanager.utils.SerialPortFinder;
import com.kyg.tjtoolmanager.utils.Utils;
import io.netty.util.internal.StringUtil;
import javafx.application.Platform;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.fxml.FXML;
import javafx.scene.control.*;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import okhttp3.Call;

import java.net.URL;
import java.util.*;
import java.util.function.Consumer;
import java.util.function.UnaryOperator;

public class ReaderEditController extends BaseController {

    @FXML
    ToggleGroup readerType;
    @FXML
    ToggleGroup conType;
    @FXML
    RadioButton rbWorkReader, rbInventoryReader;
    @FXML
    VBox vboxInventoryAdd;
    @FXML
    RadioButton rbSerialCon, rbIPCon;
    @FXML
    HBox hBoxSerial, hBoxIP, hBoxBtn;
    @FXML
    ComboBox cmbSerials, cmbKufang, cmbHuojia, cmbCeng, cmbWei;
    @FXML
    TextField txtSerialBaud, txtIP, txtIPPort;
    @FXML
    Button btnDel;

    public static String FXMLFile = "reader-view.fxml";

    private List<Shelves> shelves = new ArrayList<>();  //货架列表
    private List<Shelves> listCeng = new ArrayList<>(); //层列表
    private List<Shelves> listWei = new ArrayList<>();   //位列表
    private int houseId, jiaId, cengId, weiId;
    private Reader mReader;
    private boolean firstLoadJia = true, firstLoadCeng = true, firstLoadWei = true;

    @Override
    public void onBindData(Object object) {
        super.onBindData(object);
        if (object != null) {
            mReader = (Reader) object;
            SQLiteUtils.insertLog("传递数据:" + mReader.toString());

        } else
            SQLiteUtils.insertLog("传递数据:null");
    }

    @Override
    public void onShow() {
        super.onShow();
        SQLiteUtils.insertLog("ReaderEdit onShow");
//        btnDel.setManaged(mReader != null);
        btnDel.setVisible(mReader != null);

        double rootW = rootLayout.getWidth();
//        double rootH = rootLayout.getHeight();
//        hBoxSerial.setPrefWidth(rootW);
//        hBoxIP.setPrefWidth(rootW);
        hBoxBtn.setPrefWidth(rootW);

        TextFormatter<Integer> formatter = new TextFormatter<>(new UnaryOperator<TextFormatter.Change>() {

            @Override
            public TextFormatter.Change apply(TextFormatter.Change change) {
                String input = change.getText();
                if (input == null || input.isEmpty()) return change;
                try {
                    Integer.parseInt(input);
                    return change;
                } catch (NumberFormatException e) {
                    return null;
                }
            }
        });

        txtSerialBaud.setTextFormatter(formatter);
        txtIPPort.setTextFormatter(new TextFormatter<>(new UnaryOperator<TextFormatter.Change>() {

            @Override
            public TextFormatter.Change apply(TextFormatter.Change change) {
                String input = change.getText();
                if (input == null || input.isEmpty()) return change;
                try {
                    Integer.parseInt(input);
                    return change;
                } catch (NumberFormatException e) {
                    return null;
                }
            }
        }));

        readerType.selectedToggleProperty().addListener(rbReaderTypeChangeListener);
        conType.selectedToggleProperty().addListener(rbChangeListener);
        //串口信息
        SerialPortFinder mSerialPortFinder = new SerialPortFinder();
        String[] serialPorts = mSerialPortFinder.getAllDevicesPath();
        if (serialPorts.length == 0) {
            serialPorts = new String[]{"COM1", "COM2", "COM3"};
        }
        cmbSerials.setItems(FXCollections.observableArrayList(serialPorts));
        cmbSerials.setValue(serialPorts[0]);

        //库房信息
        String[] kufangs = new String[App.wareHouses.size()];
        for (int i = 0; i < App.wareHouses.size(); i++) {
            kufangs[i] = App.wareHouses.get(i).name;
        }
        cmbKufang.setItems(FXCollections.observableArrayList(kufangs));
        cmbKufang.valueProperty().addListener(kufangChangeListener);
        cmbHuojia.valueProperty().addListener(huojiaChangeListener);
        cmbCeng.valueProperty().addListener(cengChangeListener);
        cmbWei.valueProperty().addListener(weiChangeListener);

        //绑定数据
        if (mReader != null) {
            if (mReader.type == 1)
                rbWorkReader.setSelected(true);
            else
                rbInventoryReader.setSelected(true);
            if (mReader.conType == 1) {
                rbSerialCon.setSelected(true);
                for (int i = 0; i < serialPorts.length; i++) {
                    if (serialPorts[i].equals(mReader.serial)) {
                        cmbSerials.setValue(serialPorts[i]);
                        break;
                    }
                }
                txtSerialBaud.setText(mReader.baud + "");
            } else {
                rbIPCon.setSelected(true);
                txtIP.setText(mReader.ip);
                txtIPPort.setText(mReader.ipPort + "");
            }
            //库房信息
            for (int i = 0; i < App.wareHouses.size(); i++) {
                WareHouse wareHouse = App.wareHouses.get(i);
                if (wareHouse.houseId == mReader.houseId) {
                    cmbKufang.setValue(wareHouse.name);
                }
            }
        } else {
            cmbKufang.setValue(kufangs[0]);
        }
    }

    //读写器类型更改
    ChangeListener<Toggle> rbReaderTypeChangeListener = new ChangeListener<Toggle>() {
        @Override
        public void changed(ObservableValue<? extends Toggle> observableValue, Toggle toggle, Toggle selectedTG) {
            RadioButton rbSelected = (RadioButton) selectedTG;
            if (rbSelected.getId().equals(rbWorkReader.getId())) {
                //工作台读写器
                vboxInventoryAdd.setVisible(false);
            } else {
                vboxInventoryAdd.setVisible(true);
            }
        }
    };

    //连接方式更改
    ChangeListener<Toggle> rbChangeListener = new ChangeListener<Toggle>() {
        @Override
        public void changed(ObservableValue<? extends Toggle> observableValue, Toggle toggle, Toggle selectedTG) {
            RadioButton rbSelected = (RadioButton) selectedTG;
            if (rbSelected.getId().equals(rbSerialCon.getId())) {
                hBoxSerial.setVisible(true);
                hBoxSerial.setManaged(true);
                hBoxIP.setVisible(false);
                hBoxIP.setManaged(false);
            } else {
                hBoxSerial.setVisible(false);
                hBoxSerial.setManaged(false);
                hBoxIP.setVisible(true);
                hBoxIP.setManaged(true);
            }
        }
    };

    ChangeListener kufangChangeListener = new ChangeListener() {
        @Override
        public void changed(ObservableValue observableValue, Object o, Object t1) {
            SQLiteUtils.insertLog("选中库房：" + t1);
            //清除下拉框设置
            cmbHuojia.setItems(null);
            cmbCeng.setItems(null);
            cmbWei.setItems(null);
            //根据库房，获取货架信息
            for (int i = 0; i < App.wareHouses.size(); i++) {
                if (App.wareHouses.get(i).name.equals(t1)) {
                    houseId = App.wareHouses.get(i).houseId;
                    getShelvesInfo(houseId);
                    break;
                }
            }
        }
    };
    ChangeListener huojiaChangeListener = new ChangeListener() {
        @Override
        public void changed(ObservableValue observableValue, Object o, Object t1) {
            if (t1 == null)
                return;
            SQLiteUtils.insertLog("选中货架：" + t1);
            cmbCeng.setItems(null);
            cmbWei.setItems(null);
            //根据货架，获取层架信息
            for (int i = 0; i < shelves.size(); i++) {
                if (shelves.get(i).name.equals(t1)) {
                    jiaId = shelves.get(i).id;
                    //绑定层架
                    listCeng = shelves.get(i).child;
                    String[] cengs = new String[listCeng.size()];
                    for (int j = 0; j < listCeng.size(); j++) {
                        cengs[j] = listCeng.get(j).name;
                    }
                    cmbCeng.setItems(FXCollections.observableArrayList(cengs));
                    if (cengs.length > 0) {
                        if (firstLoadCeng && mReader != null) {
                            //修改时，绑定信息
                            firstLoadCeng = false;
                            for (int j = 0; j < listCeng.size(); j++) {
                                if (listCeng.get(j).id == mReader.cengId) {
                                    cmbCeng.setValue(cengs[j]);
                                    break;
                                }
                            }
                        } else {
                            cmbCeng.setValue(cengs[0]);
                        }
                    } else {
                        firstLoadCeng = firstLoadWei = false;
                    }
                    break;
                }
            }
        }
    };
    ChangeListener cengChangeListener = new ChangeListener() {
        @Override
        public void changed(ObservableValue observableValue, Object o, Object t1) {
            if (t1 == null)
                return;
            SQLiteUtils.insertLog("选中层架：" + t1);
            cmbWei.setItems(null);
            //根据层架，获取格口信息
            for (int i = 0; i < listCeng.size(); i++) {
                if (listCeng.get(i).name.equals(t1)) {
                    cengId = listCeng.get(i).id;
                    //绑定格口
                    listWei = listCeng.get(i).child;
                    String[] weis = new String[listWei.size()];
                    for (int j = 0; j < listWei.size(); j++) {
                        weis[j] = listWei.get(j).name;
                    }
                    cmbWei.setItems(FXCollections.observableArrayList(weis));
                    if (weis.length > 0) {
                        if (firstLoadWei && mReader != null) {
                            firstLoadWei = false;
                            for (int j = 0; j < listWei.size(); j++) {
                                if (listWei.get(j).id == mReader.weiId) {
                                    cmbWei.setValue(weis[j]);
                                    break;
                                }
                            }
                        } else {
                            cmbWei.setValue(weis[0]);
                        }
                    } else {
                        firstLoadWei = false;
                    }
                    break;
                }
            }
        }
    };
    ChangeListener weiChangeListener = new ChangeListener() {
        @Override
        public void changed(ObservableValue observableValue, Object o, Object t1) {
            if (t1 == null)
                return;
            SQLiteUtils.insertLog("选中层位：" + t1);
            for (int i = 0; i < listWei.size(); i++) {
                if (listWei.get(i).name.equals(t1)) {
                    weiId = listWei.get(i).id;
                    break;
                }
            }
        }
    };

    private void getShelvesInfo(int houseId) {
        ProgressStage progressStage = ProgressStage.of((Stage) rootLayout.getScene().getWindow(), "正在获取层架信息");
        progressStage.show();

        Map<String, String> postParams = new HashMap<>();
        postParams.put("warehouse_id", houseId + "");
        HttpService.getInstance().httpGet(HttpURL.URL(HttpURL.GET_SHELVES_INFO), postParams, new HttpBack() {
            @Override
            public void onSuccess(Call call, HttpEntity httpEntity) {
                progressStage.close();
                SQLiteUtils.insertLog("货架接口返回：" + httpEntity.toString());
                try {
                    if (httpEntity.getCode() == 1) {
                        shelves = JSONArray.parseArray(httpEntity.getData().toString(), Shelves.class);
                        String[] jias = new String[shelves.size()];
                        for (int i = 0; i < shelves.size(); i++) {
                            jias[i] = shelves.get(i).name;
                        }
                        cmbHuojia.setItems(FXCollections.observableArrayList(jias));
                        if (jias.length > 0) {
                            //判断是否为修改读写器
                            if (firstLoadJia && mReader != null) {
                                firstLoadJia = false;
                                for (int i = 0; i < shelves.size(); i++) {
                                    if (shelves.get(i).id == mReader.jiaId) {
                                        cmbHuojia.setValue(jias[i]);
                                        break;
                                    }
                                }
                            } else {
                                cmbHuojia.setValue(jias[0]);
                            }
                        } else {
                            //如果库房没有货架信息，这重置初始参数
                            firstLoadJia = firstLoadCeng = firstLoadWei = false;
                        }
                    } else {
                        StageUIHelper.getInstance().showTipAlert(httpEntity.getMsg());
                    }
                } catch (Exception ex) {
                    SQLiteUtils.insertLog("货架接口解析错误：" + ex.getMessage());
                }
            }

            @Override
            public void onFail(Call call, String e) {
                progressStage.close();
                SQLiteUtils.insertLog("层架接口错误：" + e);
                StageUIHelper.getInstance().showTipAlert(e);
            }
        });
    }

    @Override
    public void onClose() {
        super.onClose();
        SQLiteUtils.insertLog("ReaderEdit onClose");
        readerType.selectedToggleProperty().removeListener(rbReaderTypeChangeListener);
        conType.selectedToggleProperty().removeListener(rbChangeListener);
        cmbKufang.valueProperty().removeListener(kufangChangeListener);
        cmbHuojia.valueProperty().removeListener(huojiaChangeListener);
        cmbCeng.valueProperty().removeListener(cengChangeListener);
        cmbWei.valueProperty().removeListener(weiChangeListener);
    }

    @Override
    public void initialize(URL location, ResourceBundle resources) {
        super.initialize(location, resources);
        SQLiteUtils.insertLog("ReaderEdit initialize");
    }

    @FXML
    protected void onDeleteClick() {
        StageUIHelper.getInstance().showTipAlert("确认要删除该读写器吗？", new Consumer<ButtonType>() {
            @Override
            public void accept(ButtonType buttonType) {
                doDeleteReader();
            }
        });

    }

    private void doDeleteReader() {
        SQLiteUtils.deleteReader(mReader);
        StageUIHelper.getInstance().showTipAlert("删除成功", new Consumer<ButtonType>() {
            @Override
            public void accept(ButtonType buttonType) {
                Platform.runLater(new Runnable() {
                    @Override
                    public void run() {
                        onCancelClick();
                    }
                });
            }
        });
    }

    @FXML
    protected void onSaveClick() {
        boolean isAdd = true;
        Reader _reader = new Reader();
        if (mReader != null) {
            isAdd = false;
            _reader = mReader;
        }
        _reader.type = rbWorkReader.isSelected() ? 1 : 2;
        _reader.conType = rbSerialCon.isSelected() ? 1 : 2;
        if (rbSerialCon.isSelected()) {
            _reader.serial = (String) cmbSerials.getValue();
            String baud = txtSerialBaud.getText().toString().trim();
            if (StringUtil.isNullOrEmpty(baud)) {
                StageUIHelper.getInstance().showTipAlert("波特率不可为空");
                return;
            }
            _reader.baud = Integer.parseInt(baud);
        } else {
            String ip = txtIP.getText().toString().trim();
            if (!Utils.validateIp(ip)) {
                StageUIHelper.getInstance().showTipAlert("请输入正确的IP地址");
                return;
            }
            _reader.ip = ip;
            String port = txtIPPort.getText().toString().trim();
            if (StringUtil.isNullOrEmpty(port)) {
                StageUIHelper.getInstance().showTipAlert("端口不可为空");
                return;
            }
            _reader.ipPort = Integer.parseInt(port);
        }
        if (_reader.type == 2) {
            //绑定仓库货架信息
            _reader.houseId = houseId;
            _reader.jiaId = jiaId;
            _reader.cengId = cengId;
            _reader.weiId = weiId;
        }
        SQLiteUtils.insertLog("读写器信息：" + _reader.toString());

        boolean result = false;
        if (isAdd) {
            //查询该串口或网口是否已经存在
            List<Reader> readerList = SQLiteUtils.getLocalAllReader();
            for (int i = 0; i < readerList.size(); i++) {
                Reader reader = readerList.get(i);
                if (_reader.conType == 1) {
                    if (reader.serial.equals(_reader.serial)) {
                        StageUIHelper.getInstance().showTipAlert("已存在相同串口的读写器！");
                        return;
                    }
                } else if (_reader.conType == 2) {
                    if (reader.ip.equals(_reader.ip)) {
                        StageUIHelper.getInstance().showTipAlert("已存在相同网口的读写器！");
                        return;
                    }
                }
            }
            result = SQLiteUtils.insertReader(_reader);
        } else {
            result = SQLiteUtils.updateReader(_reader);
        }
        if (!result) {
            StageUIHelper.getInstance().showTipAlert("保存失败！");
        } else {
            StageUIHelper.getInstance().showTipAlert("保存成功", new Consumer<ButtonType>() {
                @Override
                public void accept(ButtonType buttonType) {
                    Platform.runLater(new Runnable() {
                        @Override
                        public void run() {
                            onCancelClick();
                        }
                    });
                }
            });
        }
    }

    @FXML
    protected void onCancelClick() {
        Stage stage = (Stage) rootLayout.getScene().getWindow();
        stage.close();
        onClose();
    }

}
